package api

import (
	"encoding/json"
	"errors"
	"fmt"
	"io/ioutil"
	"net/http"
	"os/exec"
	"strings"
	"time"
)

// FundBaseInfo 基金基本信息
type FundBaseInfo struct {
	Code        string  `json:"code"`
	Name        string  `json:"name"`
	Type        string  `json:"type"`
	NetValue    float64 `json:"net_value"`
	TotalValue  float64 `json:"total_value"`
	ChangeRate  float64 `json:"change_rate"`
	Manager     string  `json:"manager"`
	Company     string  `json:"company"`
	Established string  `json:"established"`
	Size        string  `json:"size"`
}

// FundPerformance 基金业绩信息
type FundPerformance struct {
	WeekReturn  float64 `json:"week_return"`
	MonthReturn float64 `json:"month_return"`
	ThreeMonth  float64 `json:"three_month"`
	SixMonth    float64 `json:"six_month"`
	YearReturn  float64 `json:"year_return"`
	TwoYear     float64 `json:"two_year"`
	ThreeYear   float64 `json:"three_year"`
	FiveYear    float64 `json:"five_year"`
	FromStart   float64 `json:"from_start"`
	MaxDrawdown float64 `json:"max_drawdown"`
	Volatility  float64 `json:"volatility"`
	SharpRatio  float64 `json:"sharp_ratio"`
}

// 获取基金基本信息
func GetFundBaseInfo(code string) (*FundBaseInfo, error) {
	// 优先尝试调用AKShare API服务
	baseInfo, err := getFundInfoFromAKShareAPI(code)
	if err == nil && baseInfo != nil {
		return baseInfo, nil
	}

	// 回退到执行Python脚本
	cmd := exec.Command("python", "-c", fmt.Sprintf(`
import json
try:
    import akshare as ak
    fund_info = ak.fund_info_em('%s')
    fund_name = ak.fund_name_em()
    
    # 查找基金名称和类型
    fund_name_filtered = fund_name[fund_name['基金代码'] == '%s']
    name = fund_name_filtered['基金简称'].values[0] if not fund_name_filtered.empty else ''
    fund_type = fund_name_filtered['基金类型'].values[0] if not fund_name_filtered.empty else ''
    
    # 获取基金经理信息
    fund_manager = ak.fund_manager_em('%s')
    manager_name = fund_manager['基金经理'][0] if not fund_manager.empty else ''
    company = fund_manager['所属公司'][0] if not fund_manager.empty else ''
    
    # 获取基金规模
    fund_scale = ak.fund_scale_open_em('%s')
    size = fund_scale['基金规模(亿元)'].values[0] if not fund_scale.empty else '0'
    est_date = fund_scale['成立日期'].values[0] if not fund_scale.empty else ''
    
    # 获取净值
    fund_value = ak.fund_open_fund_info_em('%s', '单位净值走势')
    latest_value = fund_value['单位净值'].values[-1] if not fund_value.empty else 0
    change_rate = fund_value['日增长率'].values[-1] if not fund_value.empty else 0
    
    result = {
        'code': '%s',
        'name': name,
        'type': fund_type,
        'net_value': float(latest_value),
        'total_value': 0.0,  # 需要其他接口获取
        'change_rate': float(change_rate.replace('%%', '')) / 100 if isinstance(change_rate, str) else float(change_rate),
        'manager': manager_name,
        'company': company,
        'established': est_date,
        'size': size + '亿元'
    }
    print(json.dumps(result))
except Exception as e:
    print(json.dumps({'error': str(e)}))
`, code, code, code, code, code, code))

	output, err := cmd.CombinedOutput()
	if err != nil {
		return nil, err
	}

	strOutput := string(output)
	if strings.Contains(strOutput, "error") {
		return nil, errors.New(strOutput)
	}

	var fundInfo FundBaseInfo
	if err := json.Unmarshal(output, &fundInfo); err != nil {
		return nil, err
	}

	return &fundInfo, nil
}

// 获取基金业绩数据
func GetFundPerformance(code string) (*FundPerformance, error) {
	// 优先尝试调用AKShare API服务
	perfData, err := getFundPerformanceFromAKShareAPI(code)
	if err == nil && perfData != nil {
		return perfData, nil
	}

	// 回退到执行Python脚本
	cmd := exec.Command("python", "-c", fmt.Sprintf(`
import json
try:
    import akshare as ak
    import numpy as np
    import pandas as pd
    
    # 获取基金历史业绩
    fund_open_fund_info = ak.fund_open_fund_info_em('%s', '历史净值明细')
    
    # 过滤数据
    if not fund_open_fund_info.empty:
        fund_open_fund_info['日期'] = pd.to_datetime(fund_open_fund_info['净值日期'])
        fund_open_fund_info['日增长率'] = fund_open_fund_info['日增长率'].str.replace('%%', '').astype(float) / 100
        
        # 计算各期收益率
        now = pd.Timestamp.now()
        week_ago = now - pd.Timedelta(days=7)
        month_ago = now - pd.Timedelta(days=30)
        three_month_ago = now - pd.Timedelta(days=90)
        six_month_ago = now - pd.Timedelta(days=180)
        year_ago = now - pd.Timedelta(days=365)
        two_year_ago = now - pd.Timedelta(days=365*2)
        three_year_ago = now - pd.Timedelta(days=365*3)
        five_year_ago = now - pd.Timedelta(days=365*5)
        
        # 获取各时间段的净值
        latest_value = fund_open_fund_info.iloc[0]['单位净值'] if len(fund_open_fund_info) > 0 else 0
        
        # 计算各期收益率
        week_return = calculate_return(fund_open_fund_info, week_ago)
        month_return = calculate_return(fund_open_fund_info, month_ago)
        three_month = calculate_return(fund_open_fund_info, three_month_ago)
        six_month = calculate_return(fund_open_fund_info, six_month_ago)
        year_return = calculate_return(fund_open_fund_info, year_ago)
        two_year = calculate_return(fund_open_fund_info, two_year_ago)
        three_year = calculate_return(fund_open_fund_info, three_year_ago)
        five_year = calculate_return(fund_open_fund_info, five_year_ago)
        
        # 计算最大回撤
        max_drawdown = calculate_max_drawdown(fund_open_fund_info)
        # 计算波动率
        volatility = calculate_volatility(fund_open_fund_info)
        # 计算夏普比率
        sharp_ratio = calculate_sharp_ratio(fund_open_fund_info)
        
        # 获取成立日期
        earliest_date = fund_open_fund_info['日期'].min()
        from_start = calculate_return(fund_open_fund_info, earliest_date)
        
        result = {
            'week_return': week_return,
            'month_return': month_return,
            'three_month': three_month,
            'six_month': six_month,
            'year_return': year_return,
            'two_year': two_year,
            'three_year': three_year,
            'five_year': five_year,
            'from_start': from_start,
            'max_drawdown': max_drawdown,
            'volatility': volatility,
            'sharp_ratio': sharp_ratio
        }
        print(json.dumps(result))
    else:
        print(json.dumps({'error': 'No data found'}))
        
except Exception as e:
    print(json.dumps({'error': str(e)}))

def calculate_return(df, start_date):
    try:
        if df.empty:
            return 0
        
        # 找到最接近start_date的记录
        filtered_df = df[df['日期'] >= start_date]
        if filtered_df.empty:
            return 0
        
        start_value = filtered_df.iloc[-1]['单位净值']
        end_value = df.iloc[0]['单位净值']
        
        if start_value == 0:
            return 0
            
        return (end_value - start_value) / start_value
    except:
        return 0

def calculate_max_drawdown(df):
    try:
        if df.empty or len(df) < 2:
            return 0
            
        # 计算回撤序列
        values = df['单位净值'].values
        max_so_far = values[0]
        max_drawdown = 0
        
        for i in range(1, len(values)):
            if values[i] > max_so_far:
                max_so_far = values[i]
            drawdown = (max_so_far - values[i]) / max_so_far
            max_drawdown = max(max_drawdown, drawdown)
            
        return max_drawdown
    except:
        return 0

def calculate_volatility(df):
    try:
        if df.empty or len(df) < 2:
            return 0
            
        # 计算日收益率的标准差
        returns = df['日增长率'].values
        return np.std(returns) * np.sqrt(252)  # 年化波动率
    except:
        return 0

def calculate_sharp_ratio(df):
    try:
        if df.empty or len(df) < 2:
            return 0
            
        # 计算夏普比率 (假设无风险利率为3%)
        returns = df['日增长率'].values
        avg_return = np.mean(returns) * 252  # 年化收益率
        vol = np.std(returns) * np.sqrt(252)  # 年化波动率
        risk_free_rate = 0.03
        
        if vol == 0:
            return 0
            
        return (avg_return - risk_free_rate) / vol
    except:
        return 0
`, code))

	output, err := cmd.CombinedOutput()
	if err != nil {
		return nil, err
	}

	strOutput := string(output)
	if strings.Contains(strOutput, "error") {
		return nil, errors.New(strOutput)
	}

	var fundPerf FundPerformance
	if err := json.Unmarshal(output, &fundPerf); err != nil {
		return nil, err
	}

	return &fundPerf, nil
}

// 从AKShare API服务获取基金基本信息
func getFundInfoFromAKShareAPI(code string) (*FundBaseInfo, error) {
	// 这里假设有一个AKShare API服务
	url := fmt.Sprintf("http://localhost:8000/api/fund/info?code=%s", code)
	
	client := http.Client{
		Timeout: 5 * time.Second,
	}
	
	resp, err := client.Get(url)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()
	
	if resp.StatusCode != http.StatusOK {
		return nil, fmt.Errorf("API request failed with status: %d", resp.StatusCode)
	}
	
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return nil, err
	}
	
	var result FundBaseInfo
	if err := json.Unmarshal(body, &result); err != nil {
		return nil, err
	}
	
	return &result, nil
}

// 从AKShare API服务获取基金业绩信息
func getFundPerformanceFromAKShareAPI(code string) (*FundPerformance, error) {
	// 这里假设有一个AKShare API服务
	url := fmt.Sprintf("http://localhost:8000/api/fund/performance?code=%s", code)
	
	client := http.Client{
		Timeout: 5 * time.Second,
	}
	
	resp, err := client.Get(url)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()
	
	if resp.StatusCode != http.StatusOK {
		return nil, fmt.Errorf("API request failed with status: %d", resp.StatusCode)
	}
	
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return nil, err
	}
	
	var result FundPerformance
	if err := json.Unmarshal(body, &result); err != nil {
		return nil, err
	}
	
	return &result, nil
} 